home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Overview / Signals / register variables < prev    next >
Encoding:
Text File  |  1994-11-18  |  2.7 KB  |  73 lines  |  [TEXT/MPS ]

  1. ======================================================
  2. Register Variables (for both Pascal and C programmers)
  3. ======================================================
  4.  
  5. If you take a look at CTestSignal.c, the C version of the signal-testing MPW tool,
  6. you will note the following code in main():
  7.  
  8.     volatile long        registerLong = 0;
  9.     
  10.     InitUFailure();
  11.  
  12.     if (code = CatchSignal()) {
  13.         fprintf(stdout, "Signal caught in main; code = %d, (registerLong = %d)\n",
  14.             code, registerLong);
  15.         return 0;
  16.     }
  17.     
  18.     registerLong = 0xffff;
  19.     
  20.     Signal(Value());
  21.  
  22. The storage specifier volatile is used in the declaration of registerLong because
  23. of a potential problem with the value of register variables at the point of the
  24. CatchSignal(). This problem can occur when using longjmp() as well.
  25.  
  26. What happens is that the compiler (being a clever little fellow) decides that a
  27. local scalar variable can be conveniently kept in a register. When the exception is
  28. raised, all non-scratch registers are restored to what they were before the
  29. CatchSignal() call. If registerLong is kept in D3, for instance, then it will have
  30. the value 0 instead of 0xffff while processing the exception.
  31.  
  32. This can be a serious problem if the register variable holds something like a
  33. handle or pointer, since you are likely to want to dispose of the block that it
  34. references if an exception occurs.
  35.  
  36. In C this potential difficulty can be avoided by declaring a variable volatile. The
  37. compiler will keep a local variable on the stack and not leave it in a register. So,
  38. the printf() displays the correct value of 65535. If you removed the volatile
  39. storage specifier, 0 would be value of registerLong when printf() was called. If there
  40. is any doubt about a variable in your C program, be volatile.
  41.  
  42.  
  43. In the Pascal PTestSignal.p tool in Main:
  44.  
  45.         registerLong:    LONGINT;
  46.  
  47.     BEGIN
  48. {InitSignals has already been done}
  49.         registerLong := 0;
  50.         
  51.         {catch Signals not otherwise caught by the program}
  52.         code := CatchSignal;
  53.         IF code <> 0 THEN BEGIN
  54.             NumToString(code, aString);
  55.             aString := Concat('Signal caught from main, code = ',aString,
  56.                 ', registerLong = ');
  57.             DoCatchOutMain(aString, registerLong);
  58.         END;
  59.         
  60.         registerLong := $FFFF;
  61.         
  62.         Signal(Value);
  63.  
  64.  
  65. The Pascal tool displays zero for the value of registerLong since the compiler keeps
  66. it in a D register. This means that you must be careful in your use of local variables
  67. when CatchSignal is involved. This is never a problem when using CatchFailures since
  68. the handler is a separate procedure and any locals of an enclosing procedure would be
  69. pulled off the stack by the handler.
  70.  
  71. Apple is investigating ways to get the same kind of control in Pascal that the
  72. volatile storage specifier gives you in C. A future version of MPW Pascal will almost
  73. certainly have this capability.